home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
xcoral
/
xcoral.lha
/
xcoral-1.72
/
init_menus.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-23
|
14KB
|
546 lines
/*
** Copyright 1989, 1992 by Lionel Fournigault
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
** This software is provided "as is" without any expressed or implied warranty.
**
**
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifndef apollo
#include <malloc.h>
#endif
#include "menus.h"
XContext SwContext;
XContext TiContext;
static ResourcesMenu rm;
static int getnbstr ();
static char *getmaxstr ();
static void show_bar ();
static VMenu *Vmenu ();
extern void Display3D ();
/*
** Function name : InitMenuRes
**
** Description : Initialisations des ressources pour les menus.
** La fonte, le foregreound, le background ainsi que
** les couleurs utilisees pour le 3D.
** Plusieurs contextes graphiques sont mis en oeuvre.
**
** Input : Le display, font, foreground, background, top_shadow et bottom_shadow.
** Ouput :
*/
void InitMenusRes ( display, font, fg, bg, ts, bs )
Display *display;
XFontStruct *font;
unsigned long fg, bg, ts, bs;
{
GC gc;
XGCValues gcv;
unsigned long gcm;
gc = DefaultGC ( display, DefaultScreen (display ));
rm.ngc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
rm.bgc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv ); /* Ne sert plus == ngc */
rm.ugc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
rm.igc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
rm.top_shadow = ts;
rm.bot_shadow = bs;
rm.font = font;
rm.fg = fg;
rm.bg = bg;
XCopyGC ( display, gc, (~0), rm.ngc );
XCopyGC ( display, gc, (~0), rm.igc );
gcm = 0;
gcm |= GCFunction; gcv.function = GXxor;
gcm |= GCPlaneMask; gcv.plane_mask = fg ^ bg;
gcm |= GCForeground; gcv.foreground = fg ^ bg;
gcm |= GCBackground; gcv.background = bg;
XChangeGC ( display, rm.igc, gcm, &gcv );
gcv.line_width = 0; gcv.font = font -> fid;
gcv.background = bg; gcv.foreground = fg;
XChangeGC ( display, rm.ngc, GCLineWidth | GCFont | GCForeground |
GCBackground, &gcv );
XCopyGC ( display, rm.ngc, (~0), rm.bgc );
XCopyGC ( display, rm.ngc, (~0), rm.ugc );
rm.height_bar = font -> ascent + font -> descent + BAR_SPACE;
TiContext = XUniqueContext ();
SwContext = XUniqueContext ();
}
/*
** Function name : MakeMenus
**
** Description : Fabrication des menus pour chacun des titres.
**
** Input : Le display, la fenetre parent, les titres, les items et la
** table des callbacks.
** Ouput : XYMenu *
*/
XYMenu *MakeMenus ( display, w, title, item, fnt )
Display *display;
Window w;
char **title;
char ***item;
void (**fnt []) ();
{
XYMenu *menu;
SWindow *sw;
XWindowAttributes att;
register int i = 0;
register int x, width;
VMenu *Vmenu ();
/* char *malloc (); */
XGetWindowAttributes ( display, w, &att );
menu = ( XYMenu * ) malloc ( sizeof ( XYMenu ));
bzero ( menu, sizeof ( XYMenu ));
menu -> width_relief = DEPTH_WIDTH;
menu -> font = rm.font;
menu -> bar_height = rm.height_bar;
menu -> bar_width = att.width + ( menu -> width_relief * 2 );
menu -> h_item = rm.font->ascent + rm.font->descent + 2 + ( 2 * menu -> width_relief );
menu -> y_menu = menu -> bar_height + 2;
menu -> titlename = title;
menu -> itemname = item;
menu -> y_title = rm.font -> ascent + 1;
menu -> parent = w;
menu -> n_last_unmapped = -1;
menu -> hmax_menu = 0;
menu -> w_under = w;
menu -> Ngc = rm.ngc;
menu -> Igc = rm.igc;
menu -> Bgc = rm.bgc;
menu -> Ugc = rm.ugc;
menu -> top_sh = rm.top_shadow;
menu -> bot_sh = rm.bot_shadow;
menu -> fg_bar = menu -> fg_menu = rm.fg;
menu -> bg_bar = menu -> bg_menu = rm.bg;
menu -> w_bar = XCreateSimpleWindow ( display, w, 0, 0, menu -> bar_width,
menu -> bar_height, 0, rm.bg, rm.bg );
XSelectInput ( display, menu->w_bar, ExposureMask | StructureNotifyMask
| VisibilityChangeMask );
menu->mapped = 0;
menu -> save = 0;
x = 2;
while ( *title != 0 ) {
width = XTextWidth ( rm.font, *title, strlen ( *title )) + 20;
*title++;
menu->w_title [i] =
XCreateSimpleWindow ( display, menu->w_bar, x, 2,
width,
menu -> h_item,
0, rm.bg, rm.bg );
menu->title_width [i] = width;
/*
* Ne sert que pour savoir si on est dans la barre des titres.
* le choix de width n'a pas d'importance.
*/
XSaveContext ( display, menu->w_title [i], TiContext, (caddr_t) width ) ;
XSelectInput ( display, menu->w_title [i], ExposureMask |
EnterWindowMask | ButtonPressMask );
menu -> no_menu = i;
sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
sw -> w = menu -> w_title [i];
sw -> type = MENU;
sw -> no_m = i;
sw -> no_i = 0;
if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
(void) fprintf ( stderr, "make_xymenus XSaveContext Error\n" );
menu->vmenu [i] = Vmenu ( display, w, menu, *item, x, *fnt, rm.bg );
if ( menu -> vmenu [i] -> height > menu -> hmax_menu )
menu -> hmax_menu = menu -> vmenu [i] -> height;
x += width;
i++;
*item++;
*fnt++;
if ( i > 10 )
break;
}
menu->nb_menus = i;
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
SetMenuPixmap ( display, menu, menu -> bar_width );
show_bar ( display, menu -> parent, menu );
return menu;
}
/*
** Function name : MouseInMenuBar
**
** Description : Comme son nom l'indique.
**
** Input : Le Display, la fenetre
** Ouput : Vrai ou Faux.
*/
int MouseInMenuBar ( display, w )
Display *display;
Window w;
{
int m;
if ( XFindContext ( display, w, TiContext, (caddr_t *) &m ) != XCNOENT )
return True;
else
return False;
}
/*
** Function name : SetMenuPixmap
**
** Description : Fabrication d'un pixmap pour sauvegarder
** les parties cachees.
** Input : Le display, le menu, largeur de la fenetre parent.
** Ouput :
*/
void SetMenuPixmap ( display, menu, width )
Display *display;
XYMenu *menu;
register int width;
{
if ( menu -> save != 0 ) {
#ifdef DEBUG
fprintf ( stderr, "Pixmap ms = %d\n", menu -> save );
#endif
XFreePixmap ( display, menu -> save );
}
#ifdef SHADOW
menu -> save = XCreatePixmap ( display,
menu -> w_under , width,
menu -> hmax_menu + SHAD + 10,
DefaultDepth ( display, DefaultScreen ( display )));
#else
menu -> save = XCreatePixmap ( display,
menu -> w_under , width,
menu -> hmax_menu + 10,
DefaultDepth ( display, DefaultScreen ( display )));
#endif
menu -> save_ok = 0; /* Ya rien dans la pixmap */
menu -> pix_width = width;
}
/*
** Function name : Vmenu
**
** Description : Fabrication des menus associes a chaque titre
** principal.
**
** Input : Le Display, la fenetre parent, menu, table des items,
** la fonte, le background.
** Ouput :
*/
static VMenu *Vmenu ( display, window, menu, item, x_title, fnt, bg )
Display *display;
Window window;
XYMenu *menu;
register char **item;
register int x_title;
void (**fnt) ();
unsigned long bg;
{
VMenu *vm;
SWindow *sw;
char *getmaxstr ();
XSetWindowAttributes att, att_io;
register int x_menu, n;
register char *maxstr;
register int nb_item;
vm = ( VMenu * ) malloc ( sizeof ( VMenu ));
bzero ( vm, sizeof ( VMenu ));
maxstr = getmaxstr ( item );
nb_item = getnbstr ( item );
vm -> height = ( nb_item * menu -> h_item ) + 6;
vm -> width = XTextWidth ( menu->font, maxstr, strlen ( maxstr )) + 26
+ ( 2 * menu -> width_relief );
x_menu = x_title;
vm -> x = x_menu;
#ifdef SHADOW
att_io.win_gravity = NorthWestGravity;
att_io.event_mask = 0;
att_io.override_redirect = False;
att_io.do_not_propagate_mask = NoEventMask;
att_io.cursor = None;
vm -> trans = XCreateWindow ( display, window, x_menu, menu -> y_menu,
vm -> width + SHAD, vm -> height + SHAD, 0, 0,
InputOutput, CopyFromParent,
CWWinGravity | CWEventMask | CWOverrideRedirect |
CWDontPropagate | CWCursor,
&att_io );
vm -> shadow = XCreateSimpleWindow ( display, vm -> trans, SHAD,
SHAD, vm->width, vm->height, 0,
BlackPixel ( display, DefaultScreen ( display )),
BlackPixel ( display, DefaultScreen ( display )));
vm -> v_frame = XCreateSimpleWindow ( display, vm -> trans, 0,
0, vm->width, vm->height, 0, bg, bg );
XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
XSelectInput ( display, vm -> trans, ExposureMask | LeaveWindowMask );
#else
vm->v_frame = XCreateSimpleWindow ( display, window, x_menu,
menu->y_menu, vm->width, vm->height, 0, bg, bg );
XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
#endif
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) == True )
att.save_under = True;
else
att.save_under = False;
#ifdef SHADOW
XChangeWindowAttributes ( display, vm -> trans, CWSaveUnder, &att );
#else
XChangeWindowAttributes ( display, vm->v_frame, CWSaveUnder, &att );
#endif
n = 0;
vm -> iname = item;
while ( *item != 0 ) {
vm->w_item [n] = XCreateSimpleWindow ( display, vm->v_frame,
3, (n * menu -> h_item) + 3,
vm->width - 6, menu -> h_item, 0,
bg, bg );
XSelectInput ( display, vm->w_item [n], ExposureMask
| EnterWindowMask );
sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
sw -> w = vm->w_item [n];
sw -> type = ITEM;
sw -> no_i = n;
sw -> no_m = menu -> no_menu;
if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
(void) fprintf ( stderr, "make_vertical_menus XSaveContext Error\n" );
vm -> func [n] = *fnt;
n++;
*item++;
*fnt++;
}
#ifdef SHADOW
XMapSubwindows ( display, vm -> trans );
XMapSubwindows ( display, vm -> v_frame );
#else
XMapSubwindows ( display, vm -> v_frame );
#endif
vm->nb_items = n;
return ( vm );
}
/*
** Function name : SetHiddenWindow
**
** Description : Initialise les parametres de la fenetre cachee.
**
** Input : Le menu, la fenetre cachee, le contexte graphique.
** Ouput :
*/
void SetHiddenWindow ( menu, w, gc )
XYMenu *menu;
Window w;
GC gc;
{
menu -> w_under = w;
menu -> Ugc = gc;
}
/*
** Function name : getnbstr
**
** Description : Pour avoir la taille d'un tableau de pointeurs
**
** Input : La tableau.
** Ouput : le nombre d'entree non vide dans le tableau.
*/
static int getnbstr ( tstr )
register char **tstr;
{
register int i = 0;
while ( *tstr != 0 ) {
i++;
*tstr++;
if ( i > 100 ) return ( 0 );
}
return ( i );
}
/*
** Function name : getmaxstr
**
** Description : Donne la plus longue chaine dans un tableau,
** en fonction de la fonte utilisee.
**
** Input : Le tableau
** Ouput : La plus grande chaine.
*/
static char *getmaxstr ( tstr )
register char **tstr;
{
register char *s;
register int i, j;
i = 0;
while ( *tstr != 0 ) {
j = strlen ( *tstr );
if ( (j=XTextWidth ( rm.font, *tstr, strlen ( *tstr ))) > i ) {
s = *tstr;
i = j;
}
tstr ++;
}
return ( s );
}
/*
** Function name : RefreshMenuBar
**
** Description : Redessine la barre des titres.
**
** Input : Le display, le menu.
** Ouput :
*/
void RefreshMenuBar ( display, menu )
Display *display;
XYMenu *menu;
{
register int i;
register char **str = menu->titlename;
XResizeWindow ( display, menu -> w_bar, menu -> bar_width,
menu -> bar_height );
Display3D ( display, menu -> w_bar,
menu -> top_sh, menu -> bot_sh,
menu -> width_relief , DEPTH_UP );
for ( i=0; i < menu->nb_menus; i++ ) {
XDrawString ( display, menu->w_title [i], menu -> Bgc, 10,
menu -> y_title + menu -> width_relief + 1,
*str, strlen ( *str ));
str++;
}
}
/*
** Function name : show_bar
**
** Description : Affichage de la barre des titres.
**
** Input : Le display, la fenetre mere, le menu.
** Ouput :
*/
static void show_bar ( display, w, menu )
Display *display;
Window w;
XYMenu *menu;
{
XEvent event;
XMapSubwindows ( display, menu->w_bar );
XMapWindow ( display, menu->w_bar );
XMapWindow ( display, w );
XFlush ( display );
XWindowEvent ( display, w, ExposureMask, &event );
XWindowEvent ( display, menu -> w_bar, ExposureMask, &event );
RefreshMenuBar ( display, menu );
}
/*
** Function name : ButtonPressInMenu
**
** Description : Comme son nom l'indique.
**
** Input : La fenetre de l'evenement, le menu.
** Ouput : Le numero du menu, sinon -1;
*/
int ButtonPressInMenu ( w, menu )
Window w;
XYMenu *menu;
{
register int i, n = -1;
for ( i=0; i < menu -> nb_menus; i++)
if ( w == menu -> w_title [i] ) {
n = i;
break;
}
return ( n );
}
/*
** Function name : DeleteMenu
**
** Description : Comme son nom l'indique.
**
** Input : Le display, le menu.
** Ouput :
*/
void DeleteMenu ( display, menu )
Display *display;
XYMenu *menu;
{
register int i, j;
SWindow *sw;
for ( i = 0; i < menu -> nb_menus; i++ ) {
for ( j=0; j < menu -> vmenu [i] -> nb_items; j++ ) {
XFindContext ( display, menu -> vmenu [i] -> w_item [j], SwContext, (caddr_t *) &sw );
if ( sw != 0 )
(void) free (( char * ) sw );
XDeleteContext ( display, menu -> vmenu [i] -> w_item [j], SwContext );
XDestroyWindow ( display, menu -> vmenu [i] -> w_item [j] );
}
#ifdef SHADOW
XDestroyWindow ( display, menu -> vmenu [i] -> trans );
#else
XDestroyWindow ( display, menu -> vmenu [i] -> v_frame );
#endif
XFindContext ( display, menu -> w_title [i], SwContext, (caddr_t *) &sw );
if ( sw != 0 )
(void) free ( ( char * ) sw );
XDeleteContext ( display, menu -> w_title [i], SwContext );
if ( menu -> vmenu [i] != 0 )
free ( ( char * ) menu -> vmenu [i] );
}
XDestroyWindow ( display,menu -> w_bar );
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
XFreePixmap ( display, menu -> save );
if ( menu != 0 )
(void) free ( ( char * ) menu );
}